---
type: tutorial
title: Envía tu primer script al navegador
i18nReady: true
description: >-
  Tutorial: Crea tu primer blog con Astro —
  Agrega interactividad del lado del cliente a tu navegación móvil con una etiqueta de script de Astro
---
import Blanks from '~/components/tutorial/Blanks.astro';
import Box from '~/components/tutorial/Box.astro';
import Checklist from '~/components/Checklist.astro';
import MultipleChoice from '~/components/tutorial/MultipleChoice.astro';
import Option from '~/components/tutorial/Option.astro';
import PreCheck from '~/components/tutorial/PreCheck.astro';
import { Steps } from '@astrojs/starlight/components';

Añadamos un botón para abrir y cerrar los enlaces en pantallas de dispositivos móviles, lo que requiere cierta interactividad con el cliente.

<PreCheck>
  - Crear un componente de menú
  - Escribir un `<script>` para que los visitantes de tu sitio puedan abrir y cerrar el menú de navegación
  - Mover tu JavaScript a un archivo `.js`.
</PreCheck>

## Construye un componente Menu

Crea un componente `<Menu />` para abrir y cerrar tu menú móvil.

<Steps>
1. Crea un archivo llamado `Menu.astro` en `src/components/`.
  

2. Copia el siguiente código en tu componente. Este crea un botón que se usará para alternar la visibilidad de los enlaces de navegación en dispositivos móviles. (Más adelante agregarás los nuevos estilos CSS en `global.css`.)

    ```astro title="src/components/Menu.astro"
    --- 
    ---
    <button aria-expanded="false" aria-controls="main-menu" class="menu">
      Menu
    </button>
    ```

3. Coloca este nuevo componente `<Menu />` justo antes de tu componente `<Navigation />` en `Header.astro`. 

    <details>
    <summary>¡Enséñame el código!</summary>

      ```astro title="src/components/Header.astro" ins={2,7}
      ---
      import Menu from './Menu.astro';
      import Navigation from './Navigation.astro';
      ---
      <header>
        <nav>
          <Menu />
          <Navigation />
        </nav>
      </header>
      ```
      </details>

4. Añade los siguientes estilos para tu componente menu, incluyendo algunos estilos responsivos:

    ```css title="src/styles/global.css" ins={2-9, 33-35, 51-53}
    /* estilos de la barra de navegación*/
    .menu {
      background-color: #0d0950;
      border: none;
      color: #fff;
      font-size: 1.2rem;
      font-weight: bold;
      padding: 5px 10px;
    }

    .nav-links {
      width: 100%;
      display: none;
      margin: 0;
    }

    .nav-links a {
      display: block;
      text-align: center;
      padding: 10px 0;
      text-decoration: none;
      font-size: 1.2rem;
      font-weight: bold;
      text-transform: uppercase;
      color: #0d0950;
    }

    .nav-links a:hover,
    .nav-links a:focus {
      background-color: #ff9776;
    }

    :has(.menu[aria-expanded="true"]) .nav-links {
      display: unset;
    }

    @media screen and (min-width: 636px) {
      .nav-links {
        margin-left: 5em;
        display: block;
        position: static;
        width: auto;
        background: none;
      }

      .nav-links a {
        display: inline-block;
        padding: 15px 20px;
      }

      .menu {
        display: none;
      }
    }
    ```
</Steps>


## Escribe tu primera etiqueta script

Tu encabezado aún no es **interactivo** porque no puede responder a la entrada del usuario, como hacer clic en el menú para mostrar u ocultar los enlaces de navegación. 

La adición de una etiqueta `<script>` proporciona JavaScript del lado del cliente para "escuchar" un evento del usuario y luego responder en consecuencia

<Steps>
1. Añade la siguiente etiqueta `<script>` a `index.astro`, justo antes de la etiqueta de cierre `</body>`.

    ```astro title="src/pages/index.astro" ins={2-9}
      <Footer />
      <script>
        const menu = document.querySelector('.menu');

        menu?.addEventListener('click', () => {
          const isExpanded = menu.getAttribute('aria-expanded') === 'true';
          menu.setAttribute('aria-expanded', `${!isExpanded}`);
        });
      </script>
    </body>
    ```

2. Comprueba de nuevo la vista previa del navegador en varios tamaños y verifica que el menú de navegación funciona, que es responsivo al tamaño de la pantalla y que responde a las entradas del usuario en esta página.
</Steps>

### Importa un archivo `.js`

En lugar de escribir JavaScript directamente en cada página, puedes mover el contenido de la etiqueta `<script>` a su propio archivo `.js` en el proyecto.

<Steps>
1. Crea `src/scripts/menu.js` (tendrás que crear una nueva carpeta `/scripts/`) y mueve tu JavaScript a ella.

    ```js title="src/scripts/menu.js"
    const menu = document.querySelector('.menu');

    menu?.addEventListener('click', () => {
      const isExpanded = menu.getAttribute('aria-expanded') === 'true';
      menu.setAttribute('aria-expanded', `${!isExpanded}`);
    });
    ```

2. Sustituye el contenido de la etiqueta `<script>` en `index.astro` por la siguiente importación de archivos:

    ```astro title="src/pages/index.astro" ins={10} del={3-8}
      <Footer />
      <script>
        const menu = document.querySelector('.menu');

        menu?.addEventListener('click', () => {
          const isExpanded = menu.getAttribute('aria-expanded') === 'true';
          menu.setAttribute('aria-expanded', `${!isExpanded}`);
        });

        import "../scripts/menu.js";
      </script>
    </body>
    ```

3. Comprueba de nuevo la vista previa del navegador a un tamaño más pequeño y verifica que el menú todavía abre y cierra los enlaces de tu navegación.


4. Añade la misma etiqueta `<script>` con la importación a tus otras dos páginas, `about.astro` y `blog.astro` y comprueba que tienes un encabezado responsivo e interactivo en cada página.

    ```astro title="src/pages/about.astro & src/pages/blog.astro" ins={2-4}
      <Footer />
      <script>
        import "../scripts/menu.js";
      </script>
    </body>
    ```
</Steps>

:::note[Conclusión]
Anteriormente habías utilizado JavaScript para construir partes de tu sitio:

- Definir dinámicamente el título y la cabecera de la página
- Mapeo a través de una lista de competencias en la página 'Acerca de'
- Visualización condicional de elementos HTML

Todos esos comandos se ejecutan en tiempo de compilación para crear HTML estático para tu sitio, y luego el código se "tira". 

**El JavaScript de una etiqueta `<script>` se envía al navegador** y está disponible para ejecutarse en función de las interacciones del usuario, como actualizar una página o cambiar una entrada.
:::



<Box icon="question-mark">

### Pon a prueba tus conocimientos

1. ¿Cuándo ejecuta Astro cualquier JavaScript escrito en el frontmatter de un componente?
    <MultipleChoice>
      <Option>
       Astro nunca ejecuta JavaScript
      </Option>
      <Option isCorrect>
        en tiempo de compilación
      </Option>
      <Option>
         Cuando un visitante pulsa un botón
      </Option>
    </MultipleChoice>

2. Opcionalmente, Astro puede enviar JavaScript al navegador para permitir:
    <MultipleChoice>
      <Option>
        que los usuarios hagan clic en los enlaces de las páginas
      </Option>
      <Option>
        tiempos de carga más rápidos
      </Option>
      <Option isCorrect>
        interactividad del lado del cliente
      </Option>
    </MultipleChoice>

3. El JavaScript del lado del cliente se enviará al navegador del usuario cuando se escriba o importe:
    <MultipleChoice>
      <Option isCorrect>
        en etiquetas `<script>`.
      </Option>
      <Option>
        entre las vallas de código de un archivo `.astro`.
      </Option>
      <Option>
        en `global.css`
      </Option>
    </MultipleChoice>

</Box>

<Box icon="check-list">

## Checklist

<Checklist>
- [ ] Puedo añadir interactividad del lado del cliente con JavaScript en una etiqueta `<script>`.
- [ ] Puedo importar un archivo `.js` en una etiqueta `<script>`.
</Checklist>

</Box>

### Recursos

[Scripts del lado del cliente en Astro](/es/guides/client-side-scripts/)
